import sha1 from 'js-sha1'
import {$get} from './ajax'
import store from '../store'
//import wx from 'jssdk'

// 获取签名
async function signature(url = location.href.split('#')[0], refresh = false) {
  let {obj: {jsapi_ticket}} = await $get('wx/getJsApi', {url, refresh})
  let nonceStr = Math.random().toString(36).substr(2)
  let timestamp = new Date().getTime()
  let str = [`jsapi_ticket=${jsapi_ticket}`, `noncestr=${nonceStr}`, `timestamp=${timestamp}`, `url=${url}`].join('&')
  return {
    timestamp,
    nonceStr,
    signature: sha1(str),
  }
}

// 微信sdk授权

async function weixin() {
  if (weixin._promise) return  weixin._promise;
  if (typeof(wx) === 'undefined') return;
  let limit = 3
  let result = {
    success() {
    },
    error() {
    }
  }
  wx.ready(() => result.success())
  wx.error(err => result.error(err))

  weixin._promise = new Promise(async function getSignature(resolve, reject, refresh) {
    let config = await signature(undefined, refresh)
    let {appid: appId} = store.getters.companyInfo
    config = {
      debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
      // , // 必填，公众号的唯一标识,
      appId,
      ...config,
      jsApiList: ['getLocation', 'openLocation', 'chooseWXPay', 'scanQRCode'] // 必填，需要使用的JS接口列表,
    }
    wx.config(config);
    let is_error = false
    result.success = () => {
      if (is_error) return;
      resolve(config)
    }
    result.error = (err) => {
      is_error = true
      limit--
      if (limit <= 0) {
        reject(err)
      } else {
        getSignature(resolve, reject, true)
      }
    }
  })
  return  weixin._promise
}


// 获取地理位置
export async function getLocation() {
  return new Promise(async (resolve, reject) => {
    await weixin()
    wx.getLocation({
      type: 'gcj02', // 默认为wgs84的gps坐标，如果要返回直接给openLocation用的火星坐标，可传入'gcj02'
      success: function (res) {
        var latitude = res.latitude; // 纬度，浮点数，范围为90 ~ -90
        var longitude = res.longitude; // 经度，浮点数，范围为180 ~ -180。
        var speed = res.speed; // 速度，以米/每秒计
        var accuracy = res.accuracy; // 位置精度
        resolve(res)
      },
      error: reject
    });
  })
}


//内置地图查看位置接口
export async function openLocation(config) {
  await weixin()
  wx.openLocation({
    latitude: 0, // 纬度，浮点数，范围为90 ~ -90
    longitude: 0, // 经度，浮点数，范围为180 ~ -180。
    name: '', // 位置名
    address: '', // 地址详情说明
    scale: 16, // 地图缩放级别,整形值,范围从1~28。默认为最大
    infoUrl: '', // 在查看位置界面底部显示的超链接,可点击跳转,
    ...config
  });
}

// 微信支付 (jssdk的，有点问题好像)
export async function chooseWXPay(config) {
  await weixin()
  return new Promise(async (resolve, reject) => {
    let {appId} = await weixin_promise_active
    config = {
      // appId,
      ...config,
      success: resolve,
      fail: reject
    }
    wx.chooseWXPay(config);
    alert(JSON.stringify(config))
  })
}

// 微信支付
export async function getBrandWCPayRequest(config, ask_ajax) {
  await weixin()
  return new Promise(async (resolve, reject) => {
    WeixinJSBridge.invoke(
      'getBrandWCPayRequest', config,
      (res) => {
        if (res.err_msg == "get_brand_wcpay_request:ok") { // 使用以上方式判断前端返回,微信团队郑重提示：res.err_msg将在用户支付成功后返回    ok，但并不保证它绝对可靠。
          new AjaxLoop(ask_ajax).start().then(resolve).catch(_ => reject('未收到支付信息,请联系管理员'))
        } else {
          const state = res.err_msg == "get_brand_wcpay_request:cancel" ? 'cancel' : res
          reject(state)
        }
      }
    );
  })
}

// 扫码
export async function scanQRCode () {
  await weixin()
  return new Promise((resolve, reject) => {
    wx.scanQRCode({
      needResult:1, // 默认为0，扫描结果由微信处理，1则直接返回扫描结果，
      scanType: ['qrCode'], // 可以指定扫二维码还是一维码，默认二者都有
      success: resolve,
      error: reject,
      fail: reject
    })
  })
}

// 每 500 ms 询问服务器是否收钱成功
class AjaxLoop {
  constructor(ajax, count = 10, time = 500) {
    this.count = count
    this.ajax = ajax
    this.time = time
  }
  async loop() {
    const isTrue = await this.ajax()
    this.count--
    if (isTrue == true) {
      return true
    } else if (this.count > 0) {
      await sleep(this.time)
      const isTrue = await this.loop()
      return isTrue
    } else {
      throw new Error(false)
    }
  }
  start () {
    return this.loop();
  }
}
